package com.hys.aa;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Date;

import cn.hutool.core.date.DateUtil;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

public class CertificateGenerator {
    public static void main(String[] args) throws Exception {
        generatePemCertificate();
    }

    private static void generatePemCertificate() throws Exception {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        // Generate key pair
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();

        // Generate certificate
        X509Certificate cert = generateCertificate(keyPair);

        // Save private key and certificate to files
        try (FileOutputStream privateKeyOut = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\192.168.1.106\\private.key");
             OutputStreamWriter pemWriter = new OutputStreamWriter(privateKeyOut)) {
            JcaPEMWriter writer = new JcaPEMWriter(pemWriter);
            writer.writeObject(privateKey);
            writer.flush();
        }

        try (FileOutputStream certificateOut = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\192.168.1.106\\certificate.pem");
             OutputStreamWriter pemWriter = new OutputStreamWriter(certificateOut)) {
            JcaPEMWriter writer = new JcaPEMWriter(pemWriter);
            writer.writeObject(cert);
            writer.flush();
        }
    }

    private static X509Certificate generateCertificate(KeyPair keyPair) throws Exception {
        // Generate the X509Certificate object
        X500Name issuerName = new X500Name("CN=192.168.1.106, O=xinLianHua, L=HaErBin, ST=HeiLongJiang, C=China");
        BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
        Date notBefore = new Date();
        Date notAfter = DateUtil.offsetDay(notBefore, 366*100); // 一百年

        X500Name subjectName = new X500Name("CN=192.168.1.106, O=xinLianHua, L=HaErBin, ST=HeiLongJiang, C=China");
        X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(
                issuerName, serialNumber, notBefore, notAfter, subjectName, keyPair.getPublic());

        ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withRSA")
                .build(keyPair.getPrivate());

        X509CertificateHolder certificateHolder = certificateBuilder.build(contentSigner);
        X509Certificate certificate = new JcaX509CertificateConverter()
                .getCertificate(certificateHolder);

        return certificate;
    }
}
